#ifndef __ORTHONOMAL_BASIS_H__
#define __ORTHONOMAL_BASIS_H__

#include "Point3D.h"
#include <math.h>

namespace Engine
{
	class OrthonomalBasis
	{


	public:

		Point3D up, v, w;

		OrthonomalBasis()
		{
			up = Point3D(0, 1, 0);
			v = Point3D(1, 0, 0);
			w = Point3D(0, 0, 1);
		}

		static Point3D ProduceOrthonomalBasis(Point3D& p_Normal, Point3D& p_pointToTransalte)
		{
			Point3D w = p_Normal.normalize();
			Point3D v(0);
			Point3D u(0);
			if (std::fabs(w.x) >  std::fabs(w.y))
			{
				float invLen = 1.f / std::sqrt(w.x * w.x + w.z * w.z);
				v = Point3D(-w.z * invLen, 0.f, w.x * invLen);
			}
			else
			{
				float invLen = 1.f / std::sqrt(w.x * w.x + w.z * w.z);
				v = Point3D(0.f, w.z * invLen, -w.y * invLen);
			}

			u = w.CrossProduct(v);
			
			return Point3D(u.dot(p_pointToTransalte), v.dot(p_pointToTransalte), w.dot(p_pointToTransalte));
		
		}

		void ProduceOrthonomalBasis(Point3D& p_w)
		{
			w = w.normalize();
			if (std::fabs(w.x) >  std::fabs(w.y))
			{
				float invLen = 1.f / std::sqrt(w.x * w.x + w.z * w.z);
				v = Point3D(-w.z * invLen, 0.f, w.x * invLen);
			}
			else
			{
				float invLen = 1.f / std::sqrt(w.x * w.x + w.z * w.z);
				v = Point3D(0.f, w.z * invLen, -w.y * invLen);
			}

			up = w.CrossProduct(v);
		}

	private:
	};
}

#endif // !__ORHTONOMAL_BASIS_H__
